import { useCallback, useState, useMemo, useReducer } from "./react-dom";
import { Component, PureComponent } from "./Component";
import {
  REACT_CONTEXT,
  REACT_FORWARD_REF_TYPE,
  REACT_MEMO,
  REACT_PROVIDER,
} from "./constant";
import { shallowEqual, wrapToVdom } from "./utils";

function createElement(type, config, children) {
  let ref; // 用来获取虚拟DOM实例的
  let key; // 用来区分同一个父亲不同儿子的
  if (config) {
    // 删除多余
    delete config.__source;
    delete config.__self;
    ref = config.ref;
    delete config.ref;
    key = config.key;
    delete config.key;
  }
  let props = { ...config };
  if (arguments.length > 3) {
    props.children = Array.prototype.slice.call(arguments, 2).map(wrapToVdom);
  } else {
    if (typeof children !== "undefined") {
      props.children = wrapToVdom(children);
    }
  }
  return {
    props,
    type,
    ref,
    key,
  };
}

function cloneElement(oldElement, newProps, children) {
  if (arguments.length > 3) {
    children = Array.prototype.slice.call(arguments, 2).map(wrapToVdom);
  } else {
    children = wrapToVdom(children);
  }
  let props = { ...oldElement.props, ...newProps, children };
  return { ...oldElement, props };
}

function createRef() {
  return {
    current: null,
  };
}
// /**
//  * 函数组件没有实例
//  * 所以通过类组件进行ref 转发
//  * @param {*} FunctionComponent
//  * @returns
//  */
// function forwardRef(FunctionComponent) {
//     return class extends Component {
//         render() {
//             return FunctionComponent(this.props, this.props.ref)
//         }
//     }
// }
function forwardRef(render) {
  return {
    $$typeof: REACT_FORWARD_REF_TYPE,
    render,
  };
}

// function createContext() {
//   function Provider({ value, children }) {
//     Provider._value = value;
//     return children;
//   }

//   function Consumer({ children }) {
//     return children(Provider._value);
//   }
//   return { Provider, Consumer };
// }

function createContext() {
  let context = { $$typeof: REACT_CONTEXT };
  context.Provider = { $$typeof: REACT_PROVIDER, _context: context };
  context.Consumer = { $$typeof: REACT_CONTEXT, _context: context };
  return context;
}

function memo(type, compare = shallowEqual) {
  return {
    $$typeof: REACT_MEMO,
    type,
    compare,
  };
}
const React = {
  createElement,
  Component,
  createRef,
  forwardRef,
  createContext,
  cloneElement,
  PureComponent,
  memo,
  useState,
  useMemo,
  useCallback,
  useReducer,
};
export default React;
